class HeapOperator {
    /**
     * 上浮调整
     * @param array 待调整的堆
     * */
    upAdjust (array) {
        let childIndex = array.length - 1;
        let parentIndex = Math.floor((childIndex - 1) / 2);
        // temp保存插入的叶子节点值，用于最后的赋值
        let temp = array[childIndex];
        while (childIndex > 0 && temp < array[parentIndex]) {
            // 无需真正交换，单向赋值即可
            array[childIndex] = array[parentIndex];
            childIndex = parentIndex;
            parentIndex = Math.floor((parentIndex - 1) / 2);
        }
        array[childIndex] = temp;
    }
    /**
     * 下沉调整
     * @param array 待调整的堆
     * @param parentIndex 要下沉的父节点
     * @param length 堆的有效大小
     * */
    downAdjust (array, parentIndex, length) {
        // temp 保存父节点值，用于最后的赋值
        let temp = array[parentIndex];
        let childIndex = 2 * parentIndex + 1;
        while (childIndex < length) {
            //如果有右孩子，且右孩子小于左孩子的值，则定位到右孩子
            if (
                childIndex + 1 < length &&
                array[childIndex + 1] < array[childIndex]
            ) {
                childIndex++;
            }
            // 如果父节点小于任何一个孩子的值，直接跳出
            if (temp <= array[childIndex]) {
                break;
            }
            // 无需真正交换，单向赋值即可
            array[parentIndex] = array[childIndex];
            parentIndex = childIndex;
            childIndex = 2 * childIndex + 1;
        }
        array[parentIndex] = temp;
    }
    /**
     * 构建堆
     * @param array 待调整的堆
     * */
    buildHeap (array) {
        // 从最后一个非叶子节点开始，一次下沉调整
        for (let i = Math.floor((array.length - 2) / 2); i >= 0; i--) {
            this.downAdjust(array, i, array.length);
        }
    }
}

let array = [1,3,2,6,5,7,8,9,10,0];
const heap = new HeapOperator();
heap.upAdjust(array)
console.log(array);
let array2 = [7,1,3,10,5,2,8,9,6];
heap.buildHeap(array2);
console.log(array2);